/*
 * @Author         : jiabao
 * @Description    :
 * @Date           : 2024-08-08 18:12:22
 * @FilePath       : \demo_cc\base\src\base_file.c
 */
#include "base_file.h"

static s32 base_file_valid(s08 *path)
{
    if (strlen(path) > BASE_PATH_LEN_MAX)
    {
        return BASE_ERROR;
    }
#ifdef _WIN32
    u08 forbidStr[] = {'/', '\\', ':', '*', '?', '<', '>', '|'};
#elif __linux__
    u08 forbidStr[] = {'/'};
#endif
    for (u32 i = 0; i < sizeof(forbidStr); i++)
    {
        if (strchr(path, forbidStr[i]))
        {
            return BASE_ERROR;
        }
    }
    return BASE_OK;
}
s32 base_get_current_path(s08 *path, s32 size)
{
    if (path == NULL || size <= 0)
    {
        FUN_PARM_ERROR_HINT(CRITICAL, __FILE__, __LINE__);
    }
    if (getcwd(path, size) == NULL)
    {
        printf("[base_get_current_path] Error getting current path\n");
        return BASE_ERROR;
    }
    printf("[base_get_current_path] current path:%s\n", path);
    return BASE_OK;
}

s32 base_print_current_path()
{
    s08 path[BASE_PATH_LEN_MAX];
    if (getcwd(path, BASE_PATH_LEN_MAX) == NULL)
    {
        printf("[base_print_current_path] get current path:%s error\n", path);
        return BASE_ERROR;
    }
    printf("[base_print_current_path] current path:%s\n", path);
    return BASE_OK;
}
s32 base_cd(s08 *path)
{
    if (path == NULL)
    {
        FUN_PARM_ERROR_HINT(CRITICAL, __FILE__, __LINE__);
    }
    // windows下 / // \\ 都是可以的
    if (chdir(path) == -1)
    {
        printf("[base_cd] Error changing directory:%s\n", path);
        return BASE_ERROR;
    }
    return BASE_OK;
}

s32 base_dir_exist(const s08 *path)
{
    if (path == NULL)
    {
        FUN_PARM_ERROR_HINT(CRITICAL, __FILE__, __LINE__);
    }

#ifdef _WIN32
    struct _stat64 info;
    int wlen = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0);
    wchar_t *wpath = malloc(wlen * sizeof(wchar_t));
    if (!wpath)
    {
        FUN_PARM_ERROR_HINT(CRITICAL, __FILE__, __LINE__);
    }
    MultiByteToWideChar(CP_UTF8, 0, path, -1, wpath, wlen);

    int result = _wstat64(wpath, &info);
    free(wpath);

    if (result != 0)
    {
        FUN_PARM_ERROR_HINT(CRITICAL, __FILE__, __LINE__);
    }

    if ((info.st_mode & S_IFDIR))
    {
        return BASE_OK;
    }
    else
    {
        FUN_PARM_ERROR_HINT(CRITICAL, __FILE__, __LINE__);
    }

#elif __linux__
    struct stat info;
    if (stat(path, &info) != 0)
    {
        FUN_PARM_ERROR_HINT(CRITICAL, __FILE__, __LINE__);
    }

    if (S_ISDIR(info.st_mode))
    {
        return BASE_OK;
    }
    else
    {
        FUN_PARM_ERROR_HINT(CRITICAL, __FILE__, __LINE__);
    }
#endif
}

s32 base_file_exist(s08 *path)
{
    if (path == NULL)
    {
        FUN_PARM_ERROR_HINT(CRITICAL, __FILE__, __LINE__);
    }
    struct stat info;

    // 调用 stat 函数获取文件或目录的信息
    if (stat(path, &info) != 0)
    {
        // 如果 stat 返回非零值，表示路径不存在
        return BASE_ERROR;
    }

    // 检查是否为文件
    if (info.st_mode & S_IFREG)
    {
        // 是目录
        return BASE_OK;
    }

    // 不是目录
    return BASE_ERROR;
}

s32 base_mkdir_bychdir(s08 *path)
{
    if (path == NULL || strlen(path) <= 0)
    {
        FUN_PARM_ERROR_HINT(CRITICAL, __FILE__, __LINE__);
    }
    s08 tempBuff[256];
    strcpy(tempBuff, path);
    s08 *ps08Token = strtok(tempBuff, "/");
    while (ps08Token)
    {
        // mkdir(ps08Token,0777);
        if (base_file_valid(ps08Token) == BASE_ERROR)
        {
            printf("[base_mkdir] path error:%s\n", ps08Token);
            return BASE_ERROR;
        }
        if (strcmp(ps08Token, "..") && strcmp(ps08Token, "."))
        {
            if (mkdir(ps08Token) == -1)
            {
                printf("[base_mkdir] Error creating directory:%s\n", ps08Token);
            }
        }
        base_cd(ps08Token);
        ps08Token = strtok(NULL, "/");
    }
    return BASE_OK;
}

s32 base_mkdir_notchdir(s08 *path)
{
    if (path == NULL || strlen(path) <= 0)
    {
        FUN_PARM_ERROR_HINT(CRITICAL, __FILE__, __LINE__);
    }
    s32 i, len;
    s08 pathTemp[100];
    strcpy(pathTemp, path);
    len = strlen(pathTemp);
    for (i = 0; i < len; i++)
    {
        if (pathTemp[i] == '\\' || pathTemp[i] == '/')
        {
            pathTemp[i] = '\0';
            if (base_dir_exist(pathTemp) == BASE_ERROR)
            {
                mkdir(pathTemp);
            }
            pathTemp[i] = '/';
        }
    }
    if (base_dir_exist(path) == BASE_ERROR)
    {
        mkdir(path);
    }
    return base_dir_exist(path);
}
/**
 * @Description:  Windows下不能删除中文文件夹
 * @param {s08} *path
 * @return {void}
 */
s32 base_rmdir(const s08 *path)
{
    if (path == NULL || strlen(path) <= 0 || base_dir_exist(path) == BASE_ERROR)
    {
        FUN_PARM_ERROR_HINT(CRITICAL, __FILE__, __LINE__);
    }
    s08 cmdBuff[BASE_PATH_LEN_MAX];
    memset(cmdBuff, 0, sizeof(cmdBuff));
#ifdef _WIN32
    sprintf(cmdBuff, "rd /s /q \"%s\"", path);
    if (system(cmdBuff) != 0)
    {
        printf("[base_rmdir] Error deleting directory:%s\n", cmdBuff);
        FUN_PARM_ERROR_HINT(CRITICAL, __FILE__, __LINE__);
    }
#elif __linux__
    sprintf(cmdBuff, "rm -rf %s", path);
    if (system(cmdBuff) != 0)
    {
        FUN_PARM_ERROR_HINT(CRITICAL, __FILE__, __LINE__);
    }
#else
#endif
    return BASE_OK;
}

s32 base_file_test()
{
    s08 pathRoot[BASE_PATH_LEN_MAX];
    s08 path1[BASE_PATH_LEN_MAX];
    s08 path2[BASE_PATH_LEN_MAX];
    base_get_current_path(pathRoot, BASE_PATH_LEN_MAX);
    base_print_current_path();
    base_cd("../build");

    s08 path3[BASE_PATH_LEN_MAX] = "新建文件夹";
    if (base_dir_exist(path3) == BASE_ERROR)
    {
        printf("%s is not exist\n", path3);
    }
    else
    {
        printf("%s is exist\n", path3);
    }

    s08 path4[BASE_PATH_LEN_MAX] = "Testing";
    if (base_dir_exist(path3) == BASE_ERROR)
    {
        printf("%s is not exist\n", path4);
    }
    else
    {
        printf("%s is exist\n", path4);
    }

    base_print_current_path();
    base_get_current_path(path1, BASE_PATH_LEN_MAX);
    base_mkdir_bychdir("72403/Desktop/open_source_libraries/demo_cc/base/build/45/78");
    base_print_current_path();
    base_cd(pathRoot);
    base_cd("../");
    base_get_current_path(path2, BASE_PATH_LEN_MAX);
    if (base_mkdir_notchdir("jia147//258") == BASE_OK)
    {
        printf("[base_file_test] mkdir success\n");
    }
    else
    {
        printf("[base_file_test] mkdir failed\n");
    }
    base_print_current_path();
    base_cd(path1);
    if (base_rmdir("72403") != BASE_OK)
    {
        printf("[base_file_test] rmdir failed\n");
    }
    else
    {
        printf("[base_file_test] rmdir success\n");
    }
    if (base_rmdir("新建文件夹") != BASE_OK)
    {
        printf("[base_file_test] rmdir failed\n");
    }
    else
    {
        printf("[base_file_test] rmdir success\n");
    }
    base_cd(path2);
    if (base_rmdir("jia147") != BASE_OK)
    {
        printf("[base_file_test] rmdir failed\n");
    }
    else
    {
        printf("[base_file_test] rmdir success\n");
    }
    return BASE_OK;
}
